#include "spline.h"
#include <assert.h>

//Spline::Spline()
//     : n(0), t(new QVector< double >(16)), f(new QVector< double >(16))
//{

//}

Spline::Spline(QVector< double > t, QVector< double > f)
    : n(t.size()), t(QVector< double >(t)), f(QVector< double >(f))
{
    setUp();
}

//    Spline::Spline(Spline s);
//    Spline::Spline(QVector< QPoint > t);

/* Metody publiczne */
void Spline::addControlPoint(QPointF point){}
void Spline::addAControlPoint(QPointF point1, QPointF point2){}
void Spline::addBControlPoint(QPointF point1, QPointF point2){}
void Spline::draw(){}
//    QPointF value(double t) {}

/* Metody prywatne */
void Spline::setUp()
{
    QVector< double > p(n + 1, 0.0);
    QVector< double > q(n + 1, 0.0);
    QVector< double > u(n + 1, 0.0);
    QVector< double > l(n + 1, 0.0); // lambdy
    QVector< double > d(n + 1, 0.0); // ilorazy roznicowe

    h.fill(0, n + 1);
    for (int k = 1; k < n + 1; k++)
        h[k] = t[k] - t[k - 1];
    for (int k = 1; k < n + 1; k++)
        l[k] = h[k] / (h[k] + h[k+1]);
    // http://en.wikipedia.org/wiki/Difference_quotient
    for (int k = 1; k < n + 1; k++)
        d[k] = 6 / (t[k + 1] - t[k - 1])
               * ( (f[k + 1] - f[k]) / h[k + 1] -
                   (f[k] - f[k - 1]) / h[k]       );

    // q[0] = u[0] = 0;
    for (int k = 1; k < n; k++)
    {
        p[k] =  l[k] * q[k - 1] + 2;
        q[k] = (l[k] - 1) / p[k];
        u[k] = (d[k] - l[k] * u[k - 1]) / p[k];
    }

    // M[0] = M[n] = 0;
    M.fill(0, n + 1);
    M[n - 1] = u[n - 1];
    for (int k = n - 2; k > 0; k--)
        M[k] = u[k] + q[k] * M[k + 1];
}
